<html>
    <head>
        <title>监听组件事件</title>
    </head>
    <body>
        <script>
            // 六、监听"子组件事件"
                            /*
                                在我们开发 <blog-post>组件时，它的一些功能可能要求我们和父级组件进行沟通。
                                
                                例如，我们可能会引入一个辅助功能来放大博文的字号，同时然页面的其他部分保持默认的字号。
                            */
                                // 在其父组件中，我们可以通过添加一个 postFontSize 数据 property来支持这个功能：

                                new Vue({
                                        el:'#blog-post-events-demo',
                                        data:{
                                          posts:[/*......*/],
                                          postFontSize:1
                                        }
                                });

                                // 它可以在模板中用来控制所有博文的字号：
                                      /*
                                          <div id="blog-posts-events-demo">
                                            <div :style="{ fontSize: postFontSize + 'em' }">
                                              <blog-post
                                                v-for="post in posts"
                                                v-bind:key="post.id"
                                                v-bind:post="post"
                                              ></blog-post>
                                            </div>
                                          </div>
                                      */

                                // 现在我们在每篇博文正文之前添加一个按钮来放大字号：
                                      Vue.component('blog-post',{
                                           props:['post'],
                                           templare:`
                                                <div class="bolg-post">
                                                     <h3>{{post.title}}</h3>
                                                     <button>
                                                        Enlarge text
                                                     </button>
                                                     <div v-html="post.content"></div>
                                                </div>
                                           `
                                      });

                                // 问题是这个按钮不会做任何事

                                /*
                                    当点击这个按钮时，我们需要告诉父级组件放大所有的博文的文本。
                                    幸好，Vue实例提供了 "自定义事件系统" 来解决这个问题。
                                */

                                //  父级组件可以像处理 native DOM 事件一样，通过 v-on 指令监听子组件实例的任意事件：

                                      /*
                                            ---在父级模板中监听子组件事件---
                                            <blog-post  v-on:enlarge-text="postFontSie+=0.1">

                                            </blog-post>
                                      */

                                // 同时"子组件"可以通过调用内建的 $emit('事件名') 方法，并传入事件名来触发事件

                                          Vue.component('blog-post',{
                                                    props:['post'],
                                                    templare:`
                                                          <div class="bolg-post">
                                                              <h3>{{post.title}}</h3>
                                                              <button v-on:click="$emit('enlarge-text')">
                                                                  Enlarge text
                                                              </button>
                                                              <div v-html="post.content"></div>
                                                          </div>
                                                    `
                                          });

                                         // 有了这个  v-on:enlarge-text="postFontSize+=0.1" 监听器，父组件就会接收该事件并更新 postFontSize的值
                          
                          
                            // ★、使用事件抛出一个值
                                   /*
                                      有的时候用一个事件来抛出来一个特定的值是十分有用的。（其实就是传递一个"事件参数"）

                                      例如，我们可能想让<blog-post>组件决定它的文本要放大多少。
                                   */

                                   // 这时候可以使用 $emit() 方法的第二个参数来提供这个值
                                           // eg:
                                                /*
                                                    <button v-on:click="$emit('enlarge-text',0.1)">
                                                        Enlarge Text
                                                    </button>
                                                */

                                   // 然后当在父组件监听这个事件的时候，我们可以通过 $event 访问到被传递的值：
                                            /*
                                                <blog-post v-on:enlarge-text="postFontSize +=$event">

                                                </blog-post>
                                            */

                                  // 或者通过"事件处理函数"来接收这个值
                                            /*
                                                <blog-post v-on:enlarge-text="onEnlargeRext">

                                                </blog-post>
                                            */

                                            // 那么，这个值将会作为第一个参数传入这个方法：

                                            methods:{
                                                onEnlargeText:function(enlargeAmount){
                                                    this.postFontSize +=enlargeAmount
                                                }
                                            }


                            // ★、在组件上使用 v-model
                                     // 自定义事件也可以用于创建"支持v-model"的自定义输入组件

                                         // 记住：
                                                  /*    
                                                      <input v-model="searchText">
                                                  */
                                                  // 等价于
                                                  /*
                                                      <input 
                                                          v-bind:value="searchText"
                                                          v-on:input="searchText"
                                                      >
                                                  */

                                                  // 当用在组件上时， v-model 则会这样：
                                                       /*
                                                          <custom-input 
                                                                  v-bind:value="searchText"
                                                                  v-on:input="searchText= $event"
                                                          >
                                                          </custom-input>
                                                       */

                                          /*
                                              为了让它正常工作，这个组件内的<input> 必须：

                                                    1、将其 value attribute 属性绑定到一个名为  value 的 prop上
                                                    2、 在其input 事件被触发时，将新的值通过自定义的input 事件抛出(事件参数)
                                          */ 
                                                  // 写成代码之后是这样的：

                                                  Vue.component('custom-input',{
                                                      props:['value'],
                                                      template:`
                                                          <input 
                                                              v-bind:value="value"
                                                              v-on:input="$emit('input',$event.target.value)"
                                                      `
                                                  })

                                                  // 现在 v-model 就应该可以在这个组件上完美的工作起来了。

                                                      // <custom-input v-model="searchText"></custom-input>
        </script>
    </body>
</html>